在 Day 13 中,我們學會了使用 ConfigMap 來達成「設定與程式碼分離」。然而,ConfigMap 是以**純文字(Plaintext)**儲存與展示,任何人只要有權限執行 kubectl get configmap -o yaml,就能一眼看光裡面的所有內容。
在現代資安實務中,絕對不能將以下資訊明文儲存:
Kubernetes Secret 就是專門用來保管這類敏感機密資料的專屬資源物件。
很多初學者常有一種誤解,以為把資料放進 Secret 就等於「高枕無憂的軍規加密」,但我們必須認清它的底層機制:
預設情況下,你在 Secret YAML 檔中看到的字串只是經過 Base64 編碼,任何人拿到這串編碼,只要執行 echo <string> | base64 -d 就能在一秒內還原成明文。
當 Secret 以檔案(Volume)形式掛載到 Pod 容器內部時,Kubernetes 會將資料存放在節點的 tmpfs(記憶體暫存檔案系統) 中,而不是寫入實體硬碟。當 Pod 被刪除時,記憶體資料會立即被清除,降低資料殘留在磁碟的風險。
在真正的生產環境(如 AWS EKS、GCP GKE)中,通常會啟用 Encryption at Rest(靜態加密),透過 KMS(Key Management Service)將儲存在 etcd 裡的 Secret 進行真正的加密保護。
| 類型 | 用途說明 |
|---|---|
Opaque |
預設類型,任意自訂的 Key-Value 鍵值對(如帳號密碼) |
kubernetes.io/tls |
專門存放 TLS/SSL 憑證(tls.crt)與私鑰(tls.key) |
kubernetes.io/dockerconfigjson |
存放私有映像檔倉庫(如 Docker Hub Private Repo)的認證資訊 |
假設我們的資料庫密碼是 MySecretPassword123,在終端機進行編碼:
echo -n "MySecretPassword123" | base64
注意:加上 -n 參數是為了避免把換行符號(Newline)也一起編碼進去。
預期輸出:
TXlTZWNyZXRQYXNzd29yZDEyMw==
建立 db-secret.yaml:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
DB_USER: cm9vdA== # "root" 的 Base64 編碼
DB_PASSWORD: TXlTZWNyZXRQYXNzd29yZDEyMw==
套用配置:
kubectl apply -f db-secret.yaml
提示:如果不想手動做 Base64 編碼,也可以使用 stringData 欄位直接寫明文,K8s 在儲存時會自動幫你轉成 Base64。
建立 secure-pod.yaml,同時展示兩種讀取方式:
DB_USER 作為環境變數注入。/etc/secrets。apiVersion: v1
kind: Pod
metadata:
name: secure-app-pod
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "sleep 3600"]
# 方式 A:注入為環境變數
env:
- name: DATABASE_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: DB_USER
# 方式 B:掛載為檔案
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-credentials
套用 Pod 配置:
kubectl apply -f secure-pod.yaml
kubectl exec secure-app-pod -- env | grep DATABASE_USER
輸出預期:
DATABASE_USER=root
kubectl exec secure-app-pod -- cat /etc/secrets/DB_PASSWORD
輸出預期:
MySecretPassword123
可以看到,在容器內部讀取時,K8s 已經自動將 Base64 還原為原本的明文字串,應用程式完全不需要自己撰寫解碼邏輯!
今天我們搞懂了敏感資料的專屬保險庫 Secret:
secretKeyRef)與記憶體磁區檔案(tmpfs Volume)兩種注入模式。到目前為止,我們的容器雖然可以讀取設定與密碼,但容器產生的所有數據(如資料庫寫入的資料)依然是暫時性的,容器一重啟資料就會蒸發。
明天 Day 16,我們將進入資料持久化的世界:「資料持久化:PersistentVolume (PV) 與 PersistentVolumeClaim (PVC)」!